package org.yacon;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * @author Evgeny Vetrov
 */
class Converters
{

    static class CharConverter implements TypeConverter<Character>
    {
        public Character convert(String value)
        {
            if (value.length() != 1)
                throw new IllegalArgumentException("'" + value + "' should be single character");
            return value.charAt(0);
        }
    }

    static class ByteConverter implements TypeConverter<Byte>
    {
        public Byte convert(String value)
        {
            try {
                return Byte.valueOf(value);
            }
            catch (NumberFormatException e) {
                throw new IllegalArgumentException("'" + value + "' should be byte");
            }
        }
    }

    static class BooleanConverter implements TypeConverter<Boolean>
    {
        public Boolean convert(String value)
        {
            value = value.toLowerCase();
            if (value.equals("true") || value.equals("yes") || value.equals("y"))
                return true;
            if (value.equals("false") || value.equals("no") || value.equals("n"))
                return false;
            throw new IllegalArgumentException("'" + value + "' should be Y(yes) or N(no)");
        }
    }

    static class DoubleConverter implements TypeConverter<Double>
    {
        public Double convert(String value)
        {
            try {
                return Double.parseDouble(value);
            }
            catch (NumberFormatException e) {
                throw new IllegalArgumentException("'" + value + "' should be double");
            }
        }
    }

    static class FloatConverter implements TypeConverter<Float>
    {
        public Float convert(String value)
        {
            try {
                return Float.valueOf(value);
            }
            catch (NumberFormatException e) {
                throw new IllegalArgumentException("'" + value + "' should be float");
            }
        }
    }

    static class IntegerConverter implements TypeConverter
    {
        public Object convert(String value)
        {
            try {
                return Integer.valueOf(value);
            }
            catch (NumberFormatException e) {
                throw new IllegalArgumentException("'" + value + "' should be integral");
            }
        }
    }

    static class LongConverter implements TypeConverter<Long>
    {
        public Long convert(String value)
        {
            try {
                return Long.valueOf(value);
            }
            catch (NumberFormatException e) {
                throw new IllegalArgumentException("'" + value + "' should be long");
            }
        }
    }

    static class ShortConverter implements TypeConverter<Short>
    {
        public Short convert(String value)
        {
            try {
                return Short.valueOf(value);
            }
            catch (NumberFormatException e) {
                throw new IllegalArgumentException("'" + value + "' should be short");
            }
        }
    }

    static class DateConverter extends AbstractParametrizedTypeConverter<Date>
    {
        public Date convert(String value)
        {
            String pattern = attrValues.get("pattern");
            if (pattern == null)
                pattern = "MM/dd/yyyy";
            SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
            try {
                return dateFormat.parse(value);
            }
            catch (ParseException e) {
                throw new IllegalArgumentException("'" + value + "' should be date with pattern " + pattern);
            }
        }
    }

    static class PatternConverter implements ParametrizedTypeConverter<String>
    {
        private Pattern pattern;

        public void init(Map<String, String> attrValues)
        {
            pattern = Pattern.compile(attrValues.get("pattern"));
        }

        public String convert(String value)
        {
            if (!pattern.matcher(value).matches())
                throw new IllegalArgumentException("'" + value + "' should match pattern " + pattern);
            return value;
        }
    }
}
